package com.easyOrder.core.mongo.log;

import com.aliyun.openservices.ons.api.Message;
import com.easyOrder.core.context.WebSession;
import com.easyOrder.core.dynamics.config.ConfigComponent;
import com.easyOrder.core.push.PushMessage;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.easyOrder.core.dynamics.config.ConfigTypes;
import com.easyOrder.core.json.JsonExceptionWrapper;
import com.easyOrder.core.push.PushResult;
import com.easyOrder.core.utils.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by yanbin on 2016/12/15.
 */
@Component
public class LogComponent {

    /**
     * spring mongodb　集成操作类
     */
    @Autowired
    protected MongoTemplate mongoTemplate;

    @Autowired
    private ConfigComponent config;

    private String configDefaultValue = "false";

    @Autowired
    private JavaMailSenderImpl mailSender;

    @Autowired
    private MailConfig mailConfig;

    public void insertExcept(JsonExceptionWrapper exception, String trace) {

        String configValue = config.getValue(ConfigTypes.logging, configDefaultValue);
        if (!configValue.equals("true"))
            return;

        Exception data = new Exception();
        data.setCode(exception.getCode());
        data.setMsg(exception.getMsg());
        data.setException(trace);
        if (MDC.get("profile") != null) {
            data.setProfile(MDC.get("profile"));
        }
        WebSession session = WebUtils.Session.get();
        if (MDC.get("ip") != null) {
            data.setIp(MDC.get("ip"));
        }
        if (MDC.get("url") != null) {
            data.setUrl(MDC.get("url"));
        }
        if (MDC.get("url_body") != null) {
            data.setBody(MDC.get("url_body"));
        }
        if (session != null) {
            if (session.getUserId() != null) {
                data.setUserId(session.getUserId().toString());
            }
            if (session.getUserName() != null) {
                data.setUserName(session.getUserName());
            }
            if (session.getBranchId() != null) {
                data.setBranchId(session.getBranchId().toString());
            }
            if (session.getBranchName() != null) {
                data.setBranchName(session.getBranchName());
            }
            if (session.getTenantId() != null) {
                data.setTenantId(session.getTenantId().toString());
            }
        }
        Date tempDate = new Date();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = format.format(tempDate);
        data.setCreatedTime(dateString);
        format = new SimpleDateFormat("yyyy-MM-dd");
        String dayString = format.format(tempDate);
        data.setDay(dayString);
        if (!StringUtils.isBlank(MDC.get("sessionId"))) {
            data.setSessionId(MDC.get("sessionId"));
        }
        try {
            mongoTemplate.insert(data);
        } catch (java.lang.Exception e) {
            config.set(ConfigTypes.logging, "false");
            e.printStackTrace();
        }
    }

    public void insertVisit(Visit data) {
        String configValue = config.getValue(ConfigTypes.logging, configDefaultValue);
        if (!configValue.equals("true"))
            return;
        Date tempDate = new Date();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = format.format(tempDate);
        data.setCreatedTime(dateString);
        format = new SimpleDateFormat("yyyy-MM-dd");
        String dayString = format.format(tempDate);
        data.setDay(dayString);
        if (!StringUtils.isBlank(MDC.get("sessionId"))) {
            data.setSessionId(MDC.get("sessionId"));
        }
        try {
            mongoTemplate.insert(data);
        } catch (java.lang.Exception e) {
            config.set(ConfigTypes.logging, "false");
            e.printStackTrace();
        }
    }

    public void insertDaily() {
        String configValue = config.getValue(ConfigTypes.logging, configDefaultValue);
        if (!configValue.equals("true"))
            return;
        Daily data = new Daily();
        Date tempDate = new Date();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = format.format(tempDate);
        data.setCreatedTime(dateString);
        format = new SimpleDateFormat("yyyy-MM-dd");
        String dayString = format.format(tempDate);
        data.setDay(dayString);
        if (MDC.get("ip") != null) {
            data.setIp(MDC.get("ip"));
        }
        if (MDC.get("profile") != null)
            data.setUserAgent(MDC.get("profile"));
        if (MDC.get("method") != null)
            data.setMethod(MDC.get("method"));
        if (MDC.get("url") != null)
            data.setUrl(MDC.get("url"));
        if (MDC.get("userId") != null)
            data.setUserId(MDC.get("userId"));
        if (!StringUtils.isBlank(MDC.get("sessionId"))) {
            data.setSessionId(MDC.get("sessionId"));
        }
        try {
            mongoTemplate.insert(data);
        } catch (java.lang.Exception e) {
            config.set(ConfigTypes.logging, "false");
            e.printStackTrace();
        }
    }

    public void insertPushMessage(PushMessage pushMessage, PushResult pushResult){
        PushMessageLog data = new PushMessageLog();
        data.setPushMessage(pushMessage);
        data.setPushResult(pushResult);
        Date tempDate = new Date();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = format.format(tempDate);
        data.setCreatedTime(dateString);
        format = new SimpleDateFormat("yyyy-MM-dd");
        String dayString = format.format(tempDate);
        data.setDay(dayString);
        try {
            mongoTemplate.insert(data);
        } catch (java.lang.Exception e) {
            config.set(ConfigTypes.logging, "false");
            e.printStackTrace();
        }
    }

    public void sendMail(Message message, String exceptionTrace) {
        MimeMessage msg = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(msg, true, "utf-8");
            helper.setFrom(mailSender.getUsername());
            helper.setTo(mailConfig.getSendMailList().split(","));
            helper.setSubject("Oops! " + mailConfig.getProfile() + "消息队列处理出问题了, 救命啊!!!");
            String encodeContent = formatMailContent(message, exceptionTrace);
            helper.setText(encodeContent, true);
            mailSender.send(msg);
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }
    }

    private String formatMailContent(Message message, String exceptionTrace) {
        String messageBody = formatBodyJson(new String(message.getBody()));
        return buildMailHTML(message.getMsgID(), new Date(), exceptionTrace, messageBody);
    }

    private String formatBodyJson(String body) {
        try {
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            JsonParser jsonParser = new JsonParser();
            JsonElement jsonElement = jsonParser.parse(body);
            return gson.toJson(jsonElement);
        } catch (java.lang.Exception e) {
            return body;
        }
    }

    public String buildMailHTML(String messageId, Date createdDate, String exceptionBody, String messageBody) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        StringBuilder builder = new StringBuilder();
        builder.append("<!DOCTYPE html>");
        builder.append("<html lang=\"en\">");
        builder.append("<head>");
        builder.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>");
        builder.append("<title>紧急求助</title>");
        builder.append("");
        builder.append("<style type=\"text/css\">");
        builder.append(".exception-content {");
        builder.append("background-color: #ffffff;");
        builder.append("color: indianred;");
        builder.append("padding: 15px 20px 20px 20px;");
        builder.append("font-family: \"open sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;");
        builder.append("font-size: 0.6em;");
        builder.append("width: 998px;");
        builder.append("height: 200px;");
        builder.append("border-style:solid;");
        builder.append("border-width:thin;");
        builder.append("overflow :auto;");
        builder.append("}");
        builder.append(".message-content {");
        builder.append("background-color: #ffffff;");
        builder.append("padding: 15px 20px 20px 20px;");
        builder.append("font-family: \"open sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;");
        builder.append("font-size: 0.6em;");
        builder.append("width: 998px;");
        builder.append("height: 200px;");
        builder.append("border-style:solid;");
        builder.append("border-width:thin;");
        builder.append("overflow :auto;");
        builder.append("}");
        builder.append(".indexfooter p {");
        builder.append("font-size: 16px;");
        builder.append("color: rgb(255, 255, 255);");
        builder.append("line-height: 70px;");
        builder.append("text-align: center;");
        builder.append("font-family: 微软雅黑;");
        builder.append("}");
        builder.append("</style>");
        builder.append("</head>");
        builder.append("<body style=\"font-size: 11em;\">");
        builder.append("<div>Message ID: {0}</div>");
        builder.append("<div>Occur Date: {1}</div>");
        builder.append("<br/>");
        builder.append("<div>Exception Stack Trace: </div>");
        builder.append("<pre class=\"exception-content\">");
        builder.append("{2}");
        builder.append("</pre>");
        builder.append("<br/><br/><br/>");
        builder.append("<div>Message Body: </div>");
        builder.append("<pre class=\"message-content\">");
        builder.append("{3}");
        builder.append("</pre>");
        builder.append("<br/>");
        builder.append("<br/>");
        builder.append("<br/>");
        builder.append("<div style=\"color: red;\"><b>Note: 如果你收到了这封邮件, 表示有非常紧急的系统错误需要您马上处理, 请第一时间处理该异常, 如果您不能处理请马上联系后台开发人员进行处理.</b></div>");
        builder.append("<div class=\"indexfooter\"><b>Copyright @2012-2017 易点餐</b></div>");
        builder.append("</body>");
        builder.append("</html>");
        return builder.toString()
                .replace("{0}", messageId)
                .replace("{1}", sdf.format(createdDate))
                .replace("{2}", exceptionBody)
                .replace("{3}", messageBody);
    }

}
